package cn.lg.soar.common.data.tree;

import cn.lg.soar.common.util.data.DataUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * 树形扁平数据（来源数据，有 parentId）
 * @author luguoxiang
 * @param <ID>
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public interface ITreeSource<ID> {

    /**
     * 获取id
     * @return
     */
    ID getId();

    /**
     * 获取父id
     * @return
     */
    ID getParentId();


    /**
     * 树形数据扁平化
     * @param tree 源数据
     * @param handler 转换函数
     * @param <ID> id类型
     * @param <S> 源数据类型
     * @param <R> 树形数据类型
     * @return
     */
    static <ID, R extends ITreeResult<R>, S extends ITreeSource<ID>> List<S> valueOf(List<R> tree, Function<R, S> handler) {
        List<S> list = new ArrayList<>(128);
        flatTree(tree, handler, list);
        return list;
    }

    /**
     * 树形数据扁平化（建议使用 valueOf 函数）
     * @param tree 树数据
     * @param handler 转换函数
     * @param list 扁平数据
     * @param <ID>
     * @param <R>
     * @param <S>
     */
    static <ID, R extends ITreeResult<R>, S extends ITreeSource<ID>> void flatTree(List<R> tree, Function<R, S> handler, List<S> list) {
        for (R r : tree) {
            list.add(handler.apply(r));
            List<R> children = r.getChildren();
            if (DataUtil.isValuable(children)) {
                flatTree(children, handler, list);
            }
        }
    }
}
